package com.qujia.station.service.impl;

import com.qujia.common.utils.DateUtils;
import com.qujia.station.domain.*;
import com.qujia.station.mapper.*;
import com.qujia.station.service.CommodityService;
import com.qujia.station.service.InventoryReportDailyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Objects;


@Service("inventoryReportDailyService")
@Slf4j
public class InventoryReportDailyServiceImpl implements InventoryReportDailyService {

    @Autowired
    private InventoryReportDailyMapper inventoryReportDailyMapper;

    @Autowired
    private CommodityService commodityService;

    @Autowired
    private WarehouseDetailsMapper warehouseDetailsMapper;

    @Autowired
    private OutboundRecordsDetailsMapper outboundRecordsDetailsMapper;

    @Autowired
    private StorageRecordsDetailsMapper storageRecordsDetailsMapper;

    @Autowired
    private OrderDetailsMapper orderDetailsMapper;

    @Autowired
    private InventoryDetailsMapper inventoryDetailsMapper;


    @Override
    public List<InventoryReportDaily> selectInventoryReportDailyList(InventoryReportDaily inventoryReportDaily) {
        return inventoryReportDailyMapper.selectInventoryReportDailyList(inventoryReportDaily);
    }


    @Override
    public InventoryReportDaily inventoryReportDailySum(InventoryReportDaily inventoryReportDaily) {
        return inventoryReportDailyMapper.inventoryReportDailySum(inventoryReportDaily);
    }

    @Override
    public void inventoryReportDailyStatistics() {
        // 先查询当前需要统计的商品
        Commodity req = new Commodity();
        Date yesterdayStartTime = DateUtils.getYesterdayStartTime();
        Date yesterdayEndTime = DateUtils.getYesterdayEndTime();
        String beginTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,yesterdayStartTime);
        String endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,yesterdayEndTime);
        req.setBeginTime(yesterdayStartTime);
        List<Commodity> commodities = commodityService.selectAllCommodityList(req);

        // 根据商品和油站 统计 前一天的商品数据
        for (Commodity commodity : commodities) {
            InventoryReportDaily inventoryReportDaily = new InventoryReportDaily();
            BeanUtils.copyProperties(commodity,inventoryReportDaily);

            InventoryReportDaily request = new InventoryReportDaily();
            request.setBeginTime(beginTime);
            request.setEndTime(endTime);
            request.setStationId(commodity.getStationId());
            request.setCommodityId(commodity.getCommodityId());
            InventoryReportDaily result = inventoryReportDailyMapper.selectOneInventoryReportDailyList(request);
            // 期初
            if(Objects.isNull(result)){
                inventoryReportDaily.setStartPeriodNum(BigDecimal.ZERO);
                inventoryReportDaily.setStartPeriodAmt(BigDecimal.ZERO);
                inventoryReportDaily.setStartPeriodUntaxedAmt(BigDecimal.ZERO);
            } else {
                inventoryReportDaily.setStartPeriodNum(request.getLastPeriodNum());
                inventoryReportDaily.setStartPeriodAmt(request.getLastPeriodAmt());
                inventoryReportDaily.setStartPeriodUntaxedAmt(request.getLastPeriodUntaxedAmt());
            }
            BigDecimal tax = BigDecimal.ONE.add(Objects.nonNull(commodity.getTaxRate()) ? commodity.getTaxRate().divide(BigDecimal.valueOf(100),2, RoundingMode.HALF_UP) : BigDecimal.ZERO);

            // 本期 + 入库
            addWarehouse(tax,beginTime,endTime,commodity,inventoryReportDaily);

            // 本期 + 调拨入库
            addStorage(tax,beginTime,endTime,commodity,inventoryReportDaily);

            // 本期 + 入数量合计
            inventoryReportDaily.setAddAllNum(inventoryReportDaily.getAddWarehouseNum().add(inventoryReportDaily.getAddStorageNum()));
            inventoryReportDaily.setAddAllAmt(inventoryReportDaily.getAddWarehouseAmt().add(inventoryReportDaily.getAddStorageAmt()));
            inventoryReportDaily.setAddAllUntaxedAmt(inventoryReportDaily.getAddWarehouseUntaxedAmt().add(inventoryReportDaily.getAddStorageUntaxedAmt()));

            // 本期- 销售
            reduceSale(tax,beginTime,endTime,commodity,inventoryReportDaily);

            // 本期 - 调拨出库
            reduceOutbound(tax,beginTime,endTime,commodity,inventoryReportDaily);

            // 本期出合计
            inventoryReportDaily.setReduceAllNum(inventoryReportDaily.getReduceSaleNum().add(inventoryReportDaily.getReduceOutboundNum()));
            inventoryReportDaily.setReduceAllAmt(inventoryReportDaily.getReduceSaleAmt().add(inventoryReportDaily.getReduceOutboundAmt()));
            inventoryReportDaily.setReduceAllUntaxedAmt(inventoryReportDaily.getReduceSaleUntaxedAmt().add(inventoryReportDaily.getReduceOutboundUntaxedAmt()));

            //盘点
            inventory(tax,beginTime,endTime,commodity,inventoryReportDaily);

            // 结存
            inventoryReportDaily.setLastPeriodNum(inventoryReportDaily.getStartPeriodNum().add(inventoryReportDaily.getAddAllNum())
                    .subtract(inventoryReportDaily.getReduceAllNum()).add(inventoryReportDaily.getAddInventoryNum()).subtract(inventoryReportDaily.getReduceInventoryNum()));
            inventoryReportDaily.setLastPeriodAmt(commodity.getSalePrice().multiply(inventoryReportDaily.getLastPeriodNum()));
            inventoryReportDaily.setLastPeriodUntaxedAmt(inventoryReportDaily.getLastPeriodAmt().divide(tax,2, RoundingMode.HALF_UP));
            inventoryReportDailyMapper.insertSelective(inventoryReportDaily);
        }
    }

    // 本期 + 入库
    private void addWarehouse(BigDecimal tax, String beginTime, String endTime, Commodity commodity, InventoryReportDaily inventoryReportDaily){
        WarehouseDetails warehouse = new WarehouseDetails();
        warehouse.setBeginTime(beginTime);
        warehouse.setEndTime(endTime);
        warehouse.setStationId(commodity.getStationId());
        warehouse.setCommodityId(commodity.getCommodityId());
        WarehouseDetails warehouseDetails = warehouseDetailsMapper.selectWarehouseSum(warehouse);
        if(Objects.isNull(warehouseDetails) || Objects.isNull(warehouseDetails.getInventoryQuantity())){
            inventoryReportDaily.setAddWarehouseNum(BigDecimal.ZERO);
            inventoryReportDaily.setAddWarehouseAmt(BigDecimal.ZERO);
            inventoryReportDaily.setAddWarehouseUntaxedAmt(BigDecimal.ZERO);
        } else {
            inventoryReportDaily.setAddWarehouseNum(BigDecimal.valueOf(warehouseDetails.getInventoryQuantity()));
            inventoryReportDaily.setAddWarehouseAmt(commodity.getSalePrice().multiply(BigDecimal.valueOf(warehouseDetails.getInventoryQuantity())));
            inventoryReportDaily.setAddWarehouseUntaxedAmt(inventoryReportDaily.getAddWarehouseAmt().divide(tax,2, RoundingMode.HALF_UP));
        }

    }

    // 本期 + 调拨入库
    private void addStorage(BigDecimal tax, String beginTime, String endTime, Commodity commodity, InventoryReportDaily inventoryReportDaily){
        StorageRecordsDetails req = new StorageRecordsDetails();
        req.setCommodityId(commodity.getCommodityId());
        req.setBeginTime(beginTime);
        req.setEndTime(endTime);
        StorageRecordsDetails storageRecordsDetails = storageRecordsDetailsMapper.selectOutboundRecordsDetails(req);
        if(Objects.isNull(storageRecordsDetails) || Objects.isNull(storageRecordsDetails.getInventoryQuantity())){
            inventoryReportDaily.setAddStorageNum(BigDecimal.ZERO);
            inventoryReportDaily.setAddStorageAmt(BigDecimal.ZERO);
            inventoryReportDaily.setAddStorageUntaxedAmt(BigDecimal.ZERO);
        }else {
            inventoryReportDaily.setAddStorageNum(BigDecimal.valueOf(storageRecordsDetails.getInventoryQuantity()));
            inventoryReportDaily.setAddStorageAmt(commodity.getSalePrice().multiply(BigDecimal.valueOf(storageRecordsDetails.getInventoryQuantity())));
            inventoryReportDaily.setAddWarehouseUntaxedAmt(inventoryReportDaily.getAddWarehouseAmt().divide(tax,2, RoundingMode.HALF_UP));
        }
    }

    // 本期- 销售
    private void reduceSale(BigDecimal tax, String beginTime, String endTime, Commodity commodity, InventoryReportDaily inventoryReportDaily){
        OrderDetails req = new OrderDetails();
        req.setBeginTime(beginTime);
        req.setEndTime(endTime);
        req.setCommodityId(commodity.getCommodityId());
        OrderDetails orderDetails = orderDetailsMapper.selectOrderDetails(req);
        if(Objects.isNull(orderDetails) || Objects.isNull(orderDetails.getCommodityNum())){
            inventoryReportDaily.setReduceSaleNum(BigDecimal.ZERO);
            inventoryReportDaily.setReduceSaleCostAmt(BigDecimal.ZERO);
            inventoryReportDaily.setReduceSaleCostUntaxedAmt(BigDecimal.ZERO);
            inventoryReportDaily.setReduceSaleAmt(BigDecimal.ZERO);
            inventoryReportDaily.setReduceSaleUntaxedAmt(BigDecimal.ZERO);
            inventoryReportDaily.setReduceSaleGrossProfit(BigDecimal.ZERO);
            inventoryReportDaily.setReduceCommodityGrossProfit(BigDecimal.ZERO);
        } else {
            inventoryReportDaily.setReduceSaleNum(BigDecimal.valueOf(orderDetails.getCommodityNum()));
            inventoryReportDaily.setReduceSaleCostAmt(commodity.getRetailPrice().multiply(BigDecimal.valueOf(orderDetails.getCommodityNum())));
            inventoryReportDaily.setReduceSaleCostUntaxedAmt(inventoryReportDaily.getReduceSaleCostAmt().divide(tax,2, RoundingMode.HALF_UP));
            inventoryReportDaily.setReduceSaleAmt(commodity.getSalePrice().multiply(BigDecimal.valueOf(orderDetails.getCommodityNum())));
            inventoryReportDaily.setReduceSaleUntaxedAmt(inventoryReportDaily.getReduceSaleAmt().divide(tax,2, RoundingMode.HALF_UP));
            inventoryReportDaily.setReduceSaleGrossProfit(inventoryReportDaily.getReduceSaleAmt().subtract(inventoryReportDaily.getReduceSaleCostAmt()));
            inventoryReportDaily.setReduceCommodityGrossProfit(inventoryReportDaily.getReduceSaleGrossProfit().divide(inventoryReportDaily.getReduceSaleAmt(),2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
        }
    }

    // 本期 - 调拨出库
    private void reduceOutbound(BigDecimal tax, String beginTime, String endTime, Commodity commodity, InventoryReportDaily inventoryReportDaily){
        OutboundRecordsDetails req = new OutboundRecordsDetails();
        req.setCommodityId(commodity.getCommodityId());
        req.setBeginTime(beginTime);
        req.setEndTime(endTime);
        OutboundRecordsDetails outboundRecordsDetails = outboundRecordsDetailsMapper.selectOutboundRecordsDetails(req);
        if(Objects.isNull(outboundRecordsDetails) || Objects.isNull(outboundRecordsDetails.getInventoryQuantity())){
            inventoryReportDaily.setReduceOutboundNum(BigDecimal.ZERO);
            inventoryReportDaily.setReduceOutboundAmt(BigDecimal.ZERO);
            inventoryReportDaily.setReduceOutboundUntaxedAmt(BigDecimal.ZERO);
        }else {
            inventoryReportDaily.setReduceOutboundNum(BigDecimal.valueOf(outboundRecordsDetails.getInventoryQuantity()));
            inventoryReportDaily.setReduceOutboundAmt(commodity.getSalePrice().multiply(BigDecimal.valueOf(outboundRecordsDetails.getInventoryQuantity())));
            inventoryReportDaily.setReduceOutboundUntaxedAmt(inventoryReportDaily.getReduceOutboundAmt().divide(tax,2, RoundingMode.HALF_UP));
        }
    }

    //盘点
    private void inventory(BigDecimal tax, String beginTime, String endTime, Commodity commodity, InventoryReportDaily inventoryReportDaily) {
        InventoryDetails req = new InventoryDetails();
        req.setStationId(commodity.getStationId());
        req.setCommodityId(commodity.getCommodityId());
        req.setStatus("1");
        req.setBeginTime(beginTime);
        req.setEndTime(endTime);
        // 盘点 +
        InventoryDetails addInventoryDetails = inventoryDetailsMapper.selectInventoryDetails(req);
        if(Objects.isNull(addInventoryDetails) || Objects.isNull(addInventoryDetails.getDifferenceNum())){
            inventoryReportDaily.setAddInventoryNum(BigDecimal.ZERO);
            inventoryReportDaily.setAddInventoryAmt(BigDecimal.ZERO);
            inventoryReportDaily.setAddInventoryUntaxedAmt(BigDecimal.ZERO);
        } else {
            inventoryReportDaily.setAddInventoryNum(BigDecimal.valueOf(addInventoryDetails.getDifferenceNum()));
            inventoryReportDaily.setAddInventoryAmt(commodity.getSalePrice().multiply(BigDecimal.valueOf(addInventoryDetails.getDifferenceNum())));
            inventoryReportDaily.setAddInventoryUntaxedAmt(inventoryReportDaily.getAddInventoryAmt().divide(tax,2, RoundingMode.HALF_UP));
        }

        // 盘点 -
        req.setStatus("2");
        InventoryDetails reduceInventoryDetails = inventoryDetailsMapper.selectInventoryDetails(req);
        if(Objects.isNull(reduceInventoryDetails) || Objects.isNull(reduceInventoryDetails.getDifferenceNum())){
            inventoryReportDaily.setReduceInventoryNum(BigDecimal.ZERO);
            inventoryReportDaily.setReduceInventoryAmt(BigDecimal.ZERO);
            inventoryReportDaily.setReduceInventoryUntaxedAmt(BigDecimal.ZERO);
        } else {
            inventoryReportDaily.setReduceInventoryNum(BigDecimal.valueOf(reduceInventoryDetails.getDifferenceNum()));
            inventoryReportDaily.setReduceInventoryAmt(commodity.getSalePrice().multiply(BigDecimal.valueOf(reduceInventoryDetails.getDifferenceNum())));
            inventoryReportDaily.setReduceInventoryUntaxedAmt(inventoryReportDaily.getReduceInventoryAmt().divide(tax,2, RoundingMode.HALF_UP));
        }

    }

}
